
#ifdef _WIN32

#include <Windows.h>
#undef max
#undef min


class config_file
{
	HKEY m_key;
public:

	enum type { system, user };

	config_file() : m_key(0)
	{
	}

	~config_file()
	{
		if(m_key)
		{
			RegCloseKey(m_key);
		}
	}

	var read(type t, const var & config_name, const var & default_value)
	{
		if(!m_key)
		{
			RegOpenKeyExA(t == user ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, "Software\\CppScript", 0, KEY_READ, &m_key );
		}

		if(m_key)
		{
			DWORD data_size=0;
			DWORD type;
			std::vector<BYTE> bytes;

			if( ERROR_SUCCESS == RegQueryValueExA(m_key, config_name.as_string().c_str(), NULL, &type, NULL, &data_size) )
			{
				bytes.resize(data_size);
				if( ERROR_SUCCESS == RegQueryValueExA(m_key, config_name.as_string().c_str(), NULL, &type, &bytes.front(), &data_size) )
				{
					if(type == REG_SZ) 
						return unpickle( (char*)&bytes.front() );
				}
			}
		}

		return default_value;
	}

	void write(type t, const var & config_name, const var & value)
	{
		if(!m_key)
		{
			if( ERROR_SUCCESS != RegOpenKeyExA(t == user ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, "Software\\CppScript", 0, KEY_WRITE, &m_key ) )
			{
				HKEY sk;
				RegOpenKeyExA( t == user ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, "Software", 0, KEY_CREATE_SUB_KEY, &sk );
				RegCreateKeyA( sk, "CppScript", &m_key );
				RegCloseKey(sk);
			}
		}

		if(m_key)
		{
			std::string str = pickle(value);
			if( ERROR_SUCCESS != RegSetValueExA( m_key, config_name.as_string().c_str(), NULL, REG_SZ, (const BYTE*)str.c_str(), str.size()) )
			{
				throw exception("config_write");
			}
		}
		else
		{
			throw exception("config_write");
		}
	}
};

#else

#include <sys/stat.h>

class config_file
{	
public:
	enum type { system, user };

	var read(type t, const var & config_name, const var & default_value)
	{
		std::string filename;
		switch(t)
		{
		case system: filename = "/etc/cppscript/"; break;
		case user: 
			filename = getenv("HOME");
			filename += "/.cppscript/";
		}
		filename += config_name.as_string();

		try
		{
			return unpickle_file(filename);
		}
		catch(...)
		{
			return default_value;
		}
	}

	void write(type t, const var & config_name, const var & value)
	{
		std::string filename;
		switch(t)
		{
		case system: filename = "/etc/cppscript"; break;
		case user: 
			filename = getenv("HOME");
			filename += "/.cppscript";
		}

		struct stat buf;

		if( stat(filename.c_str(), &buf)==-1 )
		{
			mkdir(filename.c_str(), 0755);
		}

		filename += '/';
		filename += config_name.as_string().c_str();

		pickle_file(filename, value);
	}
};

#endif
